using Godot;
using System;
using System.Threading.Tasks;

public partial class BattleManager : Node2D
{
    [Signal]
    public delegate void ClickToNextEventHandler();

    [Signal]
    public delegate void BattleEndEventHandler(Robot attacker, Robot target);

    [Signal]
    public delegate void BattleStartEventHandler();

    /// <summary>
    /// 创建战斗动画队列
    /// </summary>
    /// <param name="attacker"></param>
    /// <param name="weaponIndex"></param>
    /// <param name="target"></param>
    void BuildBattleQueue(Robot attacker, Robot target, WeaponEnemyTarget wpatk)
    {
        UIRoot.Show();
        buttonRoot.Show();
        var wptar = target.ChooseWeapon(attacker) as WeaponEnemyTarget;
        if (wpatk != null && !GameUtil.IsChildNodeOf(weaponAnimates, wpatk.WeaponAnimate))
        {
            weaponAnimates.AddChild(wpatk.WeaponAnimate);
        }
        if (wptar != null && !GameUtil.IsChildNodeOf(weaponAnimates, wptar.WeaponAnimate))
        {
            weaponAnimates.AddChild(wptar.WeaponAnimate);
        }

        if (attacker.IsPlayer || attacker.IsAlly)
        {
            leftRobot = target;
            rightRobot = attacker;
            UpdateScene(wpatk, wptar);
            // 计算命中
            var rightRate = CalcHitRate(attacker, target, wpatk);
            hitRateRight.Text = rightRate.ToString();

            // 反击的命中
            var leftRate = 0;
            if (wptar != null)
            {
                leftRate = CalcHitRate(target, attacker, wptar);
                hitRateLeft.Text = leftRate.ToString();
            }
            else
            {
                hitRateLeft.Text = "0";
            }

            QueueAnimation(attacker, target, wpatk, wptar, rightRate, leftRate);
        }
        else
        {
            leftRobot = attacker;
            rightRobot = target;
            UpdateScene(wpatk, wptar);
            // 计算命中
            var leftRate = CalcHitRate(attacker, target, wpatk);
            hitRateLeft.Text = leftRate.ToString();
            var rightRate = 0;
            if (wptar != null)
            {
                rightRate = CalcHitRate(target, attacker, wptar);
                hitRateRight.Text = rightRate.ToString();
            }
            else
            {
                hitRateRight.Text = "0";
            }
            QueueAnimation(attacker, target, wpatk, wptar, leftRate, rightRate);
        }
    }

    async Task RunAttackAction(Robot attacker, Robot target, WeaponEnemyTarget wp, int attackerHitRate, BattleType battle)
    {
        string ani;
        // 判断攻击方决定动画
        if (attacker.IsPlayer || attacker.IsAlly)
        {
            ani = "attack_left";
        }
        else
        {
            ani = "attack_right";
        }
        int dmg = 0;
        // 如果命中 ， 计算伤害
        if (RandomPercent() <= attackerHitRate)
        {
            dmg = attacker.AttackTarget(target, wp);
        }
        AttackInfo(attacker, battle);
        var animate = wp.WeaponAnimate;
        animate.Play(ani, wp);
        await ToSignal(animate, nameof(BaseWeaponAnimate.OnAttackEnd));
        await ToSignal(this, SignalName.ClickToNext);
        animate.Play("RESET", wp);
        AttackResult(target, dmg);
    }

    async Task<bool> IsTargetDetah(Robot attacker, Robot target)
    {
        // 如果被攻击方死亡 ， 直接结算
        if (target.IsDeath)
        {
            // 玩家机体才算经验
            if (attacker.IsPlayer)
            {
                // 获得战斗经验
                var exp = CalcBattleExp(attacker, target);
                // 如果敌人死亡 ，获得经验及金钱
                if (target.IsDeath)
                {
                    exp += CalcKillExp(attacker, target);
                }
                int lv = attacker.AddExp(exp);
                BattleResoutInfo(attacker, target, exp, lv);
            }
            else
            {
                BattleResoutInfo(attacker, target, 0, 0);
            }
            await ToSignal(this, SignalName.ClickToNext);
            EndBattle(attacker, target);
            return true;
        }
        return false;
    }

    async void QueueAnimation(Robot attacker, Robot target, WeaponEnemyTarget weaponFromAttacker, WeaponEnemyTarget weaponFromTarget, int attackerHitRate, int targetHitRate)
    {
        // 攻方进攻		
        await RunAttackAction(attacker, target, weaponFromAttacker, attackerHitRate, BattleType.Attack);
        await ToSignal(this, SignalName.ClickToNext);
        var isTargetDetah = await IsTargetDetah(attacker, target);
        if (isTargetDetah) return;
        // 被攻击方尝试反击
        if (weaponFromTarget != null)
        {
            // 有武器说明可以反击
            await RunAttackAction(target, attacker, weaponFromTarget, targetHitRate, BattleType.BeatBack);
            isTargetDetah = await IsTargetDetah(target, attacker);
            if (isTargetDetah) return;
        }
        else
        {
            // 没有武器说明不能反击
            BeatNotResout(target);
        }
        await ToSignal(this, SignalName.ClickToNext);
        // 攻方可能再次攻击		
        var rate = ReAttackRate(attacker, target);
        if (RandomPercent() <= rate)
        {
            // 再次发动攻击
            await RunAttackAction(attacker, target, weaponFromAttacker, attackerHitRate, BattleType.ReAttack);
            // 如果被攻击方死亡 ， 直接结算
            isTargetDetah = await IsTargetDetah(attacker, target);
            if (isTargetDetah) return;
        }
        await ToSignal(this, SignalName.ClickToNext);
        if (weaponFromTarget != null)
        {
            // 被攻方可能再次攻击
            rate = ReAttackRate(target, attacker);
            if (RandomPercent() <= rate)
            {
                await RunAttackAction(attacker, target, weaponFromAttacker, attackerHitRate, BattleType.ReAttack);
                // 如果被攻击方死亡 ， 直接结算
                isTargetDetah = await IsTargetDetah(target, attacker);
                if (isTargetDetah) return;
            }
        }
        await ToSignal(this, SignalName.ClickToNext);
        // 结算结果 ： 
        isTargetDetah = await IsTargetDetah(attacker, target);
        if (isTargetDetah) return;
        if (attacker.IsPlayer)
        {
            // 获得战斗经验
            var exp = CalcBattleExp(attacker, target);
            // 如果敌人死亡 ，获得经验及金钱
            if (target.IsDeath)
            {
                exp += CalcKillExp(attacker, target);
            }
            int lv = attacker.AddExp(exp);
            BattleResoutInfo(attacker, target, exp, lv);
        }
        else
        {
            // 获得战斗经验
            var exp = CalcBattleExp(target, attacker);
            // 如果敌人死亡 ，获得经验及金钱
            if (target.IsDeath)
            {
                exp += CalcKillExp(target, attacker);
            }
            int lv = target.AddExp(exp);
            BattleResoutInfo(target, attacker, exp, lv);
        }
        await ToSignal(this, SignalName.ClickToNext);
        EndBattle(attacker, target);
    }

    public void StartBattle(Robot currentRobot, Robot currentTaretRobot, WeaponEnemyTarget wp)
    {
        EmitSignal(SignalName.BattleStart);
        BuildBattleQueue(currentRobot, currentTaretRobot, wp);
    }

    private void OnInputWatcherGuiInput()
    {
        if (!UIRoot.Visible) return;
        EmitSignal(SignalName.ClickToNext);
    }

    void EndBattle(Robot attacker, Robot target)
    {
        UIRoot.Hide();
        buttonRoot.Hide();
        // 移除武器动画
        // leftWeaponAnimate?.QueueFree();
        // rightWeaponAnimate?.QueueFree();
        // weaponAnimates.RemoveChild(leftWeaponAnimate);
        // weaponAnimates.RemoveChild(rightWeaponAnimate);
        // 战斗结束
        EmitSignal(SignalName.BattleEnd, attacker, target);
    }
}
